define(['backbone', 'underscore'],
    function (Backbone, _) {



        /*!
         * backbone.iobind - Backbone.sync replacement
         * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
         * MIT Licensed
         */

        /**
         * # Backbone.sync
         *
         * Replaces default Backbone.sync function with socket.io transport
         *
         * ### Assumptions
         *
         * Currently expects active socket to be located at `window.socket`,
         * `Backbone.socket` or the sync'ed model own socket.
         * See inline comments if you want to change it.
         * ### Server Side
         *
         *     socket.on('todos:create', function (data, fn) {
 *      ...
 *      fn(null, todo);
 *     });
         *     socket.on('todos:read', ... );
         *     socket.on('todos:update', ... );
         *     socket.on('todos:delete', ... );
         *
         * @name sync
         */
        Backbone.sync = function (method, model, options) {
            var getUrl = function (object) {
                if (!(object && object.url)) return null;
                return _.isFunction(object.url) ? object.url() : object.url;
            };

            var cmd = getUrl(model).split('/')
                , namespace = (cmd[0] !== '') ? cmd[0] : cmd[1]; // if leading slash, ignore

            var params = _.extend({
                req : namespace + ':' + method
            }, options);

            params.data = model.toJSON() || {};

            //fixed this to work with backbone-relational fetch
            if (_.isEmpty(params.data)) {
                params.data = options.data;
            }

            // If your socket.io connection exists on a different var, change here:
            var io = model.socket || window.socket || Backbone.socket;

            io.emit(namespace + ':' + method, params.data, function (err, data) {
                if (err) {
                    options.error(err);
                } else {
                    options.success(data);
                }
            });
        };

        return Backbone;
    });